﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExcelToSql.Code
{
    class DataImportTable : System.Data.DataTable
    {

        internal Type GetColumnType(int colIndex, ref int colSize)
        {
            int rowsToCheck = 0;

            rowsToCheck = Program.Configuration.RowsToCheck < this.Rows.Count ? Program.Configuration.RowsToCheck : this.Rows.Count;


            // Check for Boolean
            for (int i = 0; i < rowsToCheck; i++)
            {
                bool parse = false;
                if (Boolean.TryParse(this.Rows[i][colIndex].ToString(), out parse) == false)
                    break;
                else if (i == rowsToCheck - 1)
                    return typeof(Boolean);
            }

            // Check for DateTime
            for (int i = 0; i < rowsToCheck; i++)
            {
                DateTime parse = DateTime.Now;
                if (DateTime.TryParse(this.Rows[i][colIndex].ToString(), out parse) == false)
                    break;
                else if (i == rowsToCheck - 1)
                    return typeof(DateTime);
            }

            // Check for byte
            for (int i = 0; i < rowsToCheck; i++)
            {
                byte parse = 0;
                if (Byte.TryParse(this.Rows[i][colIndex].ToString(), out parse) == false)
                    break;
                else if (i == rowsToCheck - 1)
                    return typeof(Byte);
            }

            // Check for integer
            for (int i = 0; i < rowsToCheck; i++)
            {
                int parse = 0;
                if (Int32.TryParse(this.Rows[i][colIndex].ToString(), out parse) == false)
                    break;
                else if (i == rowsToCheck - 1)
                    return typeof(Int32);
            }

            // Check for BigInt
            for (int i = 0; i < rowsToCheck; i++)
            {
                long parse = 0;
                if (Int64.TryParse(this.Rows[i][colIndex].ToString(), out parse) == false)
                    break;
                else if (i == rowsToCheck - 1)
                    return typeof(Int64);
            }

            // Check for Double
            for (int i = 0; i < rowsToCheck; i++)
            {
                double parse = 0;
                if (Double.TryParse(this.Rows[i][colIndex].ToString(), out parse) == false)
                    break;
                else if (i == rowsToCheck - 1)
                    return typeof(Double);
            }

            // Otherwise, just return a string
            try
            {
                string[] vals = this.Rows.Cast<DataRow>()
                                    .Select(r => (r[colIndex] == DBNull.Value) ? "" : r[colIndex].ToString())
                                    .ToArray();

                colSize = vals.Max(v => v.Length);
            }
            catch
            {
                colSize = 1;
            }

            return typeof(String);

        }

        internal System.Data.DataTable ToDataTable(Type[] types)
        {
            DataTable output;

            output = this.Clone();
            for (int i = 0; i < types.Length; i++)
                output.Columns[i].DataType = types[i];

            foreach (DataRow row in this.Rows)
                output.ImportRow(row);

            return output;
        }
    }
}
